package com.alpha.gateway.controller;

import com.alpha.core.entity.AlphaEntity;
import com.alpha.core.exception.AlphaException;
import com.alpha.core.http.AlphaHttpContext;
import com.alpha.core.http.Response;
import com.alpha.core.utils.*;
import com.alpha.feign.common.entity.Tenant;
import com.alpha.feign.common.entity.User;
import com.alpha.gateway.service.AuthenticationService;
import com.alpha.gateway.service.FeignClientService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * 登录认证相关接口
 *
 * @author chenruwan
 * @since 2022-01-01
 */
@Tag(name = "登录认证")
@RestController
@RequiredArgsConstructor
public class AuthenticationController {
    private final FeignClientService feignClientService;
    private final AuthenticationService authenticationService;

    @PostMapping("/auth/login")
    @Operation(summary = "账号密码登录")
    @Parameter(name = "username", description = "用户名", required = true)
    @Parameter(name = "password", description = "密码", required = true)
    @Parameter(name = "captcha", description = "验证码")
    public Response<Map<String, String>> login(@RequestBody Map<String, String> parameters, ServerHttpRequest request) {
        String username = parameters.get("username");
        String password = parameters.get("password");
        Assert.notEmpty(username, "用户名不能为空");
        Assert.notEmpty(password, "密码不能为空");

        User user = feignClientService.queryUser(username, password);
        if (user == null) {
            return Response.failure(HttpStatus.BAD_REQUEST, "账号或密码错误");
        }

        if (Boolean.FALSE.equals(user.getEnabled())) {
            authenticationService.saveUserLog(user, user.getTenantId(), false, request);
            return Response.failure(HttpStatus.BAD_REQUEST, "账号已被关闭");
        }

        try {
            authenticationService.checkTenant(user);
        } catch (AlphaException e) {
            authenticationService.saveUserLog(user, user.getTenantId(), false, request);
            return Response.failure(HttpStatus.BAD_REQUEST, e.getMessage());
        }

        authenticationService.saveUserLog(user, user.getTenantId(), true, request);
        return Response.success(authenticationService.makeToken(user));
    }

    @PostMapping("/auth/tenant/{id}")
    @Operation(summary = "切换租户")
    public Response<Map<String, String>> changeTenant(@PathVariable Long id, ServerHttpRequest request) {
        Long userId = Long.parseLong(AlphaHttpContext.getUserId());

        User user = feignClientService.getUser(userId);
        if (user == null) {
            return Response.failure(HttpStatus.BAD_REQUEST, "未查询到用户信息");
        }

        if (AlphaEntity.isEffectiveId(user.getTenantId())) {
            authenticationService.saveUserLog(user, id, false, request);
            return Response.failure(HttpStatus.BAD_REQUEST, "当前用户没有多租户权限");
        }

        Tenant tenant = feignClientService.getTenant(id);
        if (tenant == null) {
            authenticationService.saveUserLog(user, id, false, request);
            return Response.failure(HttpStatus.BAD_REQUEST, "所选企业不存在");
        }

        user.setTenantId(id);
        authenticationService.saveUserLog(user, id, false, request);
        return Response.success(authenticationService.makeToken(user));
    }

    @PostMapping("/auth/sms")
    @Operation(summary = "获取短信验证码")
    public Response<Object> sendSms(String mobile) {
        return Response.message("验证码获取成功" + mobile);
    }

    @PostMapping("/auth/sms/captcha")
    @Operation(summary = "短信验证码登录")
    public Response<Object> checkSmsCaptcha(String mobile, String captcha) {
        return Response.success(mobile + captcha);
    }

    @PostMapping("/auth/logout")
    @Operation(summary = "退出登录")
    public Response<Object> logout() {
        return Response.message("退出登录成功");
    }
}
